﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
using ClassRoomServer.Packets;
using Newtonsoft.Json;

namespace ClassRoomServer
{
    public class MessengerConnection
    {
        public Socket client;
        public UserInfo _UserInfo = new UserInfo();
        private MessengerServer server;

        public MessengerConnection(Socket client, MessengerServer server)
        {
            this.client = client;
            this.server = server;
        }

        public MessengerConnection(Socket client, UserInfo userInfo, MessengerServer server)
        {
            this.client = client;
            this._UserInfo = userInfo;
            this.server = server;    
        }
                
        private byte[] message = new byte[4];
		private byte[] data;
		int total = 0;

        public void Start()
        {
            try
            {              
                // Listen for messages.
                client.BeginReceive(message, 0, message.Length,
					SocketFlags.None, new AsyncCallback(OnGetSize), null);
            }
            catch (SocketException se)
            {
            }
        }

		private void OnGetSize(IAsyncResult ar)
		{
			try
			{
				int recv = client.EndReceive(ar);
				int dataSize = BitConverter.ToInt32(message, 0);
				data = new byte[dataSize];
				total = 0;
				client.BeginReceive(data, total, data.Length - total,
							SocketFlags.None,
							new AsyncCallback(OnMsgReceived), null);
			}
			catch (Exception e)
			{
			}

		}

		public void OnMsgReceived(IAsyncResult asyn)
        {
			try
			{
				total += client.EndReceive(asyn);
				if (total == data.Length)
				{
					server.DeliverMessage(data, total, this);

					message = new byte[4];
					client.BeginReceive(message, 0, 4, SocketFlags.None, new AsyncCallback(OnGetSize), null);
				}
				else
				{
					client.BeginReceive(data, total, data.Length - total,
					   SocketFlags.None,
					   new AsyncCallback(OnMsgReceived), null);
				}
			}
			catch (Exception e)
			{
			}
        }

        public void Close()
        {
            try
            {                
                client.Close();
            }
            catch (Exception err)
            {
            }
        }

		public void ReceiveMessage(byte[] data, int bytesRead)
		{
			byte[] lengthData = BitConverter.GetBytes(bytesRead);
			byte[] messageTotal = new byte[lengthData.Length + data.Length];
			Array.Copy(lengthData, 0, messageTotal, 0, lengthData.Length);
			Array.Copy(data, 0, messageTotal, 4, data.Length);
			client.Send(messageTotal, 0, messageTotal.Length, SocketFlags.None);
		}

        //public void ReceiveMessage(object obj, ObjectType t)
        //{
        //    XmlSerializer serializer = null;
        //    switch (t)
        //    {
        //        case ObjectType.UserInRoom:
        //            serializer = new XmlSerializer(typeof(List<UserInfo>));
        //            break;
        //        //case ObjectType.ListCharacters:
        //        //    serializer = new XmlSerializer(typeof(List<CharacterInfo>));
        //        //    break;
        //        //case ObjectType.AddGarbages:
        //        //    serializer = new XmlSerializer(typeof(List<GarbageInfo>));
        //        //    break;
        //        //case ObjectType.Weather:
        //        //    serializer = new XmlSerializer(typeof(String));
        //        //    break;
        //        //case ObjectType.CharacterID_Disconnect:
        //        //    serializer = new XmlSerializer(typeof(Int32));
        //        //    break;
        //    }
        //    MemoryStream ms = new MemoryStream();
        //    serializer.Serialize(ms, obj);

        //    byte[] objData = ms.ToArray();
        //    byte[] dataType = BitConverter.GetBytes((int)t);
        //    byte[] messageData = new byte[4 + objData.Length];
        //    Array.Copy(dataType, messageData, 4);
        //    Array.Copy(objData, 0, messageData, 4, objData.Length);
        //    byte[] lengthData = BitConverter.GetBytes(messageData.Length);

        //    byte[] messageTotal = new byte[lengthData.Length + messageData.Length];
        //    Array.Copy(lengthData, 0, messageTotal, 0, lengthData.Length);
        //    Array.Copy(messageData, 0, messageTotal, 4, messageData.Length);

        //    client.Send(messageTotal, 0, messageTotal.Length, SocketFlags.None);
        //}

        public void ReceiveMessage(object obj, ObjectType t)
        {
            JsonSerializer serializer = new JsonSerializer();
            string output = JsonConvert.SerializeObject(obj);
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] objData = encoding.GetBytes(output);
            byte[] dataType = BitConverter.GetBytes((int)t);
            byte[] messageData = new byte[4 + objData.Length];
            Array.Copy(dataType, messageData, 4);
            Array.Copy(objData, 0, messageData, 4, objData.Length);
            byte[] lengthData = BitConverter.GetBytes(messageData.Length);

            byte[] messageTotal = new byte[lengthData.Length + messageData.Length];
            Array.Copy(lengthData, 0, messageTotal, 0, lengthData.Length);
            Array.Copy(messageData, 0, messageTotal, 4, messageData.Length);

            client.Send(messageTotal, 0, messageTotal.Length, SocketFlags.None);
        }
    }
}
